package com.ywt.cda.core.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.ibatis.session.SqlSession;
import org.springframework.util.Assert;

import com.ywt.cda.core.dao.page.Page;

@SuppressWarnings("unchecked")
public abstract class IBatisGenericDao {

    public static final String POSTFIX_INSERT = ".insert";
    
    public static final String POSTFIX_INSERT_BATCH = ".insertBatch";

    public static final String POSTFIX_UPDATE = ".update";

    public static final String POSTFIX_UPDATE_SELECTIVE = ".updateSelective";

    public static final String POSTFIX_UPDATE_KEY = ".updateByPrimaryKeySelective";

    public static final String POSTFIX_DELETE = ".deleteByPrimaryKey";

    public static final String POSTFIX_GET = ".selectByPrimaryKey";

    public static final String POSTFIX_SELECT = ".list";

    public static final String POSTFIX_COUNT = ".count";

    public static final String POSTFIX_FORUPDATE = ".forUpdate";

    public static final int PAGE_SIZE = 30;
    @Resource
    private SqlSession sqlSession;
    
    /**
     * 以下为增删改部分================================================================
     * =======================
     */
    public  SqlSession getSqlSession(){
    	return this.sqlSession;
    }
    /**
     * 
     * @description insert(新增一个对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param o
     * @return Serializable
     * @exception
     * @since 1.0.0
     */
    public Serializable insert(BaseEntity o) {
        Assert.notNull(o);
        return (Serializable) this.getSqlSession().insert(o.getClass().getSimpleName() + POSTFIX_INSERT, o);
    }
    
    /**
     * 
     * @description insert(新增一组对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param o
     * @return Serializable
     * @exception
     * @since 1.0.0
     */
    public <T> void insertBatch(List<T> list) {
    	if(list.size() > 0) {
    		this.getSqlSession().insert(list.get(0).getClass().getSimpleName() + POSTFIX_INSERT_BATCH, list);
    	}
    }

    /**
     * 
     * @description update(更新对象的所有值)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param o
     *            void
     * @exception
     * @since 1.0.0
     */
    @Deprecated
    public void update(BaseEntity o) {
        Assert.notNull(o);
        this.getSqlSession().update(o.getClass().getSimpleName() + POSTFIX_UPDATE, o);
    }

    /**
     * 
     * @description updateSelective(根据现有值选择性更新对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param o
     *            void
     * @exception
     * @since 1.0.0
     */
    public void updateByPrimaryKeySelective(BaseEntity o) {
        Assert.notNull(o);
        this.getSqlSession().update(o.getClass().getSimpleName() + POSTFIX_UPDATE_KEY, o);
    }

    /**
     * 
     * @description updateSelective(根据现有值选择性更新对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param o
     *            void
     * @exception
     * @since 1.0.0
     */
    public void updateSelective(BaseEntity o) {
        Assert.notNull(o);
        this.getSqlSession().update(o.getClass().getSimpleName() + POSTFIX_UPDATE_SELECTIVE, o);
    }

    /**
     * 以下为根据条件获取某个对象============================================================
     * ===========================
     */
    public <T> T get(Class<T> entityClass, Serializable object) {
        return (T) get(entityClass.getSimpleName() + POSTFIX_GET, object);
    }

    public int delete(Class entityClass, Serializable object) {
        return this.getSqlSession().delete(entityClass.getSimpleName() + POSTFIX_DELETE, object);
    }

    /**
     * 
     * @description get(根据实例对象或id获取单一的对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param <T>
     * @param statement
     * @param object
     * @return T
     * @exception
     * @since 1.0.0
     */
    public <T> T get(String statement, Serializable object) {
        Assert.notNull(object);
        T o = (T) this.getSqlSession().selectOne(statement, object);
        return o;
    }

    public <T> T getEntityByMap(Class<T> entityClass, Map map) {
        return (T) getEntityByMap(entityClass.getSimpleName() + POSTFIX_GET, map);
    }

    /**
     * 
     * @description getEntityByMap(根据传入的map参数获取单一对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param <T>
     * @param statement
     * @param map
     * @return T
     * @exception
     * @since 1.0.0
     */
    public <T> T getEntityByMap(String statement, Map map) {
        Assert.notNull(statement);
        Assert.notNull(map);
        map.put("findBy", "True");
        return (T) this.getSqlSession().selectOne(statement, map);
    }

    /**
     * 以下为根据条件获取list和分页查询======================================================
     * =================================
     */

    public <T> List<T> query(Class<T> entityClass, Serializable object) {
        return query(entityClass.getSimpleName() + POSTFIX_SELECT, object);
    }

    /**
     * 
     * @description query(根据普通类查询获取list对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param <T>
     * @param statement
     * @param object
     * @return List<T>
     * @exception
     * @since 1.0.0
     */
    public <T> List<T> query(String statement, Serializable object) {
        Assert.notNull(object);
        return this.getSqlSession().selectList(statement, object);
    }

    public <T> List<T> queryListByMap(Class<T> entityClass, Map map) {
        return queryListByMap(entityClass.getSimpleName() + POSTFIX_SELECT, map);
    }

    /**
     * 
     * @description queryListByMap(根据map对象获取list对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param <T>
     * @param statement
     * @param map
     * @return List<T>
     * @exception
     * @since 1.0.0
     */
    public <T> List<T> queryListByMap(String statement, Map map) {
        Assert.notNull(map);
        map.put("findBy", "True");
        return this.getSqlSession().selectList(statement, map);
    }

    public <T> Integer queryCount(Class<T> entityClass, Serializable object) {
        return (Integer) this.getSqlSession().selectOne(entityClass.getSimpleName() + POSTFIX_COUNT, object);
    }

    /**
     * 
     * @description queryCount(根据普通对象获取list对象)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param <T>
     * @param statementName
     * @param domain
     * @return Integer
     * @exception
     * @since 1.0.0
     */
    public <T> Integer queryCount(String statementName, Serializable object) {
        Assert.notNull(object);
        return (Integer) this.getSqlSession().selectOne(statementName, object);
    }

    public <T> Integer queryCountByMap(Class<T> entityClass, Map map) {
        String statementName = entityClass.getSimpleName() + POSTFIX_COUNT;
        return queryCountByMap(statementName, map);
    }

    /**
     * 
     * @description queryCount(根据传入多个参数[map形式]获取查询数目，重载先前的)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param <T>
     * @param statementName
     * @param map
     * @return Integer
     * @exception
     * @since 1.0.0
     */
    public Integer queryCountByMap(String statementName, Map map) {
        Assert.notNull(map);
        map.put("findBy", "True");
        return (Integer) this.getSqlSession().selectOne(statementName, map);
    }

    public Page queryPaged(Class entityClass, Map<String, String> parameterObject,Page page) {
        return queryPaged(entityClass.getSimpleName() + POSTFIX_SELECT,parameterObject,page);
    }
    public Page queryPaged_(Class entityClass, Map<String, Object> parameterObject,Page page) {
        return queryPaged_(entityClass.getSimpleName() + POSTFIX_SELECT,parameterObject,page);
    }
    /**
     * 
     * @description queryPaged(根据传入的map得到list，记录总数，分页)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param countStatementId
     *            sql统计语句
     * @param statementId
     *            sql查询语句
     * @param parameterObject
     *            参数
     * @return Page
     * @exception
     * @since 1.0.0
     */
    public Page queryPaged(String statementId, Map<String, String> parameterObject,Page page) {
        Object result= this.getSqlSession().selectList(statementId, parameterObject,page);
        page.setResult(result);
        return page;
    }
    public Page queryPaged_(String statementId, Map<String, Object> parameterObject,Page page) {
        Object result= this.getSqlSession().selectList(statementId, parameterObject,page);
        page.setResult(result);
        return page;
    }
    private int getTotalPage(int count, int pageSize) {
        if (count == 0){
        	return 0;
        }
            
        int totalPage = (count + pageSize - 1) / pageSize + 1;
        return totalPage;
    }

    /**
     * 
     * @description updateStatement(自定义语句更新)
     * @conditions (这里描述这个方法适用条件 – 可选)
     * @param statement
     * @param parameterObject
     *            void
     * @exception
     * @since 1.0.0
     */
    public int updateStatement(String statement, Map parameterObject) {
        Assert.notNull(parameterObject);
        return this.getSqlSession().update(statement, parameterObject);
    }

    /**
     * lock a row. SRX
     */
    public <T> T getLock(Class<T> entityClass, Serializable o) {
        Assert.notNull(o);
        return (T) this.getSqlSession().selectOne(entityClass.getSimpleName() + POSTFIX_FORUPDATE, o);
    }
    
   
    
    
}
